#ifndef _FUNCTIONS_H_
#define _FUNCTIONS_H_

#include "headers.h"
#include "macros.h"
#include "planckmapping.h"

using namespace std;

extern "C"
{
	void initColorTemperatureTex();
	void setTextureFilterMode(bool bLinearFilter);
	void initCuda(void *h_volume, cudaExtent volumeSize);
	void initTransferTex();
	void bindVolumeTexture(void *h_volume, cudaExtent volumeSize);
	void freeCudaBuffers();
	void render_temperature_kernel(dim3 gridSize, dim3 blockSize, uint *d_output, uint imageW, uint imageH,
		float density, float brightness, float transferOffset, float transferScale,
		int samplingMaxSteps, float samplingStep,
		float3 boxMin, float3 boxMax, cudaExtent volumeSize);
	void render_color_kernel(dim3 gridSize, dim3 blockSize, uint *d_output, uint imageW, uint imageH,
		float density, float brightness, float transferOffset, float transferScale,
		int samplingMaxSteps, float samplingStep,
		float3 boxMin, float3 boxMax, cudaExtent volumeSize, int channel);
	void copyInvViewMatrix(float *invViewMatrix, size_t sizeofMatrix);
	void copyNearFar(float* nearFar, size_t sizeofNearFar);
	void reconstruct_color_kernel(dim3 gridSize, dim3 blockSize, 
		float* volumeData, uchar* visualHull, 
		int cameraIndex, uint *d_output, uint imageW, uint imageH,
		float density, float brightness, float transferOffset, float transferScale, 
		int samplingMaxSteps, float samplingStep,
		float3 boxMin, float3 boxMax,
		cudaExtent volumeSize, int channel);
	void reconstruct_temperature_kernel(dim3 gridSize, dim3 blockSize,
		float* volumeData, uchar* visualHull,
		int cameraIndex, uint *d_output, uint imageW, uint imageH,
		float density, float brightness, float transferOffset, float transferScale,
		int samplingMaxSteps, float samplingStep,
		float3 boxMin, float3 boxMax,
		cudaExtent volumeSize, unsigned long iteration);
	void upgradeVolumeData(cudaExtent volumeSize);
	void compute_weight_kernel(short* pixelX, short* pixelY, const int pixelSize, unsigned int* deviceFlameVoxelIndex, unsigned int flameVoxelSize,
		const int camIdx, const int camCount,
		const uint imageW, const uint imageH,
		const float3 boxMin, const float3 boxMax, const float voxelLength,
		const int voxelStart, const int voxelEnd,
		const uint3 voxelSize, const int presetVoxelSize,
		float* weight, unsigned int* indexFlameVoxel, unsigned int* weightSize);

	void render_color_temperature_kernel(dim3 gridSize, dim3 blockSize, uint *d_output, uint imageW, uint imageH,
		float density, float brightness, float transferOffset, float transferScale,
		int samplingMaxSteps, float samplingStep,
		float3 boxMin, float3 boxMax, cudaExtent volumeSize, int channel);

	void reconstruct_color_temperature_kernel(dim3 gridSize, dim3 blockSize,
		float* volumeData, uchar* visualHull,
		int cameraIndex, uint *d_output, uint imageW, uint imageH,
		float density, float brightness, float transferOffset, float transferScale,
		int samplingMaxSteps, float samplingStep,
		float3 boxMin, float3 boxMax,
		cudaExtent volumeSize, int channel);

	void generate_visual_hull_color_temperature_kernel_resize_octree(
		dim3 gridSize, dim3 blockSize,
		VisualHullType* visualHull,
		uint imageW, uint imageH,
		cudaExtent volumeSize, Octree* oct, uint oct_index, ResizeImage* gResizeImageData);

	void generate_visual_hull_color_temperature_kernel3(
		dim3 gridSize, dim3 blockSize,
		VisualHullType* visualHull,
		uint imageW, uint imageH,
		cudaExtent volumeSize, Octree* oct,Octree* oct_t,uint* quere, uint oct_index);

	void generate_visual_hull_color_temperature_kernel2(
		dim3 gridSize, dim3 blockSize,
		VisualHullType* visualHull,
		uint imageW, uint imageH,
		cudaExtent volumeSize,Octree* oct, uint oct_index);

	void generate_visual_hull_color_temperature_kernel(
		dim3 gridSize, dim3 blockSize,
		VisualHullType* visualHull,
		uint imageW, uint imageH,
		cudaExtent volumeSize);

	extern "C"
		void smooth_visual_hull(dim3 gridSize, dim3 blockSize,
			VisualHullType* visualHull,
			cudaExtent volumeSize, int offset);

	void bindVisualHullTexture(void *h_volume, cudaExtent volumeSize);
}
void GenerateSimCameraParam_yLarge();
void readData();

void computeFPS();

void renderTemperature();

void display();

void idle();

void keyboard(unsigned char key, int x, int y);

void mouse(int button, int state, int x, int y);

void motion(int x, int y);

int iDivUp(int a, int b);

void reshape(int w, int h);

void cleanup();

void initGL(int *argc, char **argv);

void initPixelBuffer();

void *loadRawFile(char *filename, size_t size);

int chooseCudaDevice(int argc, const char **argv, bool bUseOpenGL);

void runSingleTest(const char *ref_file, const char *exec_path);

uint3 ind2Coo(int i, cudaExtent e);

void convertTemperature2RGB();

void GenerateSimCameraParam_zLarge();


void generateVisualHull_resize_octree();
void generateVisualHull3();
void generateVisualHull2();
void generateVisualHull();
void smoothViualHull();


void interporateCameraParameter();
void modifyImage(string inputName1, string inputName2, string outputName);
void GetSubImage(char* srcName, int originalX, int originalY, int dstWidth, int dstHeight, char* dstName);
void GetSubImage(int originalX, int originalY, int endX, int endY, char* srcName, char* dstName);
void ComputeError(char* image1, char* image2);
void video2image();
void GenerateSmokeCameraParam();
void checkImage();
bool particle2grid(int frame);
void ComputeTemperatureRMSError(char* input, char* result,
	int minx, int miny, int minz, int maxx, int maxy, int maxz);
bool readVisualHull(string filename);

void showTemperatureColor();
void generateColorBar();
void computeTemperatureColorError();
void generateDeltaImage(char* image1, char* image2, char* outName);
void generateSingleChannelImage(char* image, int channel);

void enhanceBlueChannel(char* srcImgName, char* dstImgName);
void mergeSingleImage(char* redImageName, char* greenImageName, char*blueImageName, char* outName);
void writePlanckColor();


uint coo2ind(int x, int y, int z, cudaExtent gridSize);
void renderImages2014();
void convertTDataPaper2014();
void generateVisualHullPaper2014();
void renderImagesPaper2014();
void recontructImages2014();
void reconstructPaper2014();
void convertRGB2TPaper2014(vector<vector<float> > &tImages);

int findT(vector<struct node> &func2, int temper, struct node* t_node);
void ReadFunc(vector<struct node> &func);
void ReadFunc2(vector<struct node> &func2);
int BinarySearch(vector<struct node> &func, double value);
void preprocessingPaper2014();

void getMinYFlameImage();
void getXInfoFlameImage();
void getXInfoFlameImage2();
void getTemplate();

void testwww();

//float3 normalize(float3 v)
//{
//	float n = norm(v);
//	float3 r;
//	r.x = v.x / n;
//	r.y = v.y / n;
//	r.z = v.z / n;
//	return r;
//}

#endif // _FUNCTIONS_H_
